package vip.youngboy.freejump.db;

import org.activiti.engine.impl.util.CollectionUtil;
import org.springframework.jdbc.core.JdbcTemplate;
import vip.youngboy.freejump.db.constrants.DBType;
import vip.youngboy.freejump.db.model.DBColumn;
import vip.youngboy.freejump.db.model.DBTable;

import java.util.*;

/**
 * 数据库表操作
 */
public abstract class TableOperator {

    protected DBTable<? extends DBColumn> DBTable;

    protected JdbcTemplate jdbcTemplate;

    public TableOperator(DBTable<? extends DBColumn> DBTable, JdbcTemplate jdbcTemplate) {
        this.DBTable = DBTable;
        this.jdbcTemplate = jdbcTemplate;
    }

    public abstract DBType supportDBType();

    public void createTable() {
    }

    public void dropTable() {
        if (this.isTableCreated()) {
            String sql = "drop table " + this.DBTable.getName() + "";
            this.jdbcTemplate.execute(sql);
        }
    }

    public boolean isTableCreated() {
        return false;
    }

    public void addColumn(DBColumn DBColumn) {
    }

    public void updateColumn(DBColumn DBColumn) {
    }

    public void dropColumn(String columnName) {
    }

    public void insertData(Map<String, Object> data) {
        StringBuilder sql = new StringBuilder();
        sql.append("INSERT INTO " + this.DBTable.getName());
        StringBuilder columnNameSql = new StringBuilder();
        StringBuilder paramNameSql = new StringBuilder();
        List<Object> param = new ArrayList();
        Iterator var6 = data.entrySet().iterator();

        while (var6.hasNext()) {
            Map.Entry<String, Object> entry = (Map.Entry) var6.next();
            if (columnNameSql.length() > 0) {
                columnNameSql.append(",");
                paramNameSql.append(",");
            }

            columnNameSql.append((String) entry.getKey());
            paramNameSql.append("?");
            param.add(entry.getValue());
        }

        sql.append("(" + columnNameSql + ") VALUES(" + paramNameSql + ")");
        this.jdbcTemplate.update(sql.toString(), param.toArray());
    }

    public void deleteData(Object id) {
        String sql = "DELETE FROM " + this.DBTable.getName() + " where " + this.DBTable.getPkColumn().getName() + " = ?";
        this.jdbcTemplate.update(sql, new Object[]{id});
    }

    public void deleteData(Map<String, Object> param) {
        if (param.isEmpty()) {
            throw new RuntimeException("删除表[" + this.DBTable.getComment() + "(" + this.DBTable.getName() + ")]时，条件参数为空(会导致全表数据清空)");
        } else {
            StringBuilder sql = new StringBuilder();
            sql.append("DELETE FROM " + this.DBTable.getName() + " where ");
            List<Object> paramList = new ArrayList();
            Iterator var4 = param.entrySet().iterator();

            while (var4.hasNext()) {
                Map.Entry<String, Object> entry = (Map.Entry) var4.next();
                if (sql.toString().endsWith("?")) {
                    sql.append(" and ");
                }

                sql.append((String) entry.getKey() + " = ?");
                paramList.add(entry.getValue());
            }

            this.jdbcTemplate.update(sql.toString(), paramList.toArray());
        }
    }

    public void updateData(Map<String, Object> data) {
        Object id = data.get(this.DBTable.getPkColumn().getName());
        if (id == null) {
            throw new RuntimeException("操作更新表[" + this.DBTable.getComment() + "(" + this.DBTable.getName() + ")]时，参数中有没主键[" + this.DBTable.getPkColumn().getComment() + "(" + this.DBTable.getPkColumn().getName() + ")]");
        } else {
            StringBuilder sql = new StringBuilder();
            sql.append("UPDATE " + this.DBTable.getName() + " SET ");
            List<Object> param = new ArrayList();
            Iterator var5 = data.entrySet().iterator();

            while (var5.hasNext()) {
                Map.Entry<String, Object> entry = (Map.Entry) var5.next();
                if (!((String) entry.getKey()).equals(this.DBTable.getPkColumn().getName())) {
                    if (sql.toString().endsWith("?")) {
                        sql.append(" , ");
                    }

                    param.add(entry.getValue());
                    sql.append((String) entry.getKey() + " = ?");
                }
            }

            sql.append(" WHERE " + this.DBTable.getPkColumn().getName() + " = ?");
            param.add(id);
            this.jdbcTemplate.update(sql.toString(), param.toArray());
        }
    }

    public Map<String, Object> selectData(List<String> columnName, Object id) {
        Map<String, Object> param = new HashMap();
        param.put(this.DBTable.getPkColumn().getName(), id);
        List<Map<String, Object>> list = this.selectData(columnName, (Map) param);
        return !list.isEmpty() ? (Map) list.get(0) : null;
    }

    public Map<String, Object> selectData(Object id) {
        Map<String, Object> param = new HashMap();
        param.put(this.DBTable.getPkColumn().getName(), id);
        List<Map<String, Object>> list = this.selectData((Map) param);
        return !list.isEmpty() ? (Map) list.get(0) : null;
    }

    public List<Map<String, Object>> selectData(Map<String, Object> param) {
        return this.selectData((List) null, (Map) param);
    }

    public List<Map<String, Object>> selectData(List<String> columnName, Map<String, Object> param) {
        StringBuilder sql = new StringBuilder();
        if (CollectionUtil.isEmpty(columnName)) {
            sql.append("SELECT * FROM " + this.DBTable.getName());
        } else {
            sql.append("SELECT");

            String cn;
            for (Iterator var4 = columnName.iterator(); var4.hasNext(); sql.append(" " + cn)) {
                cn = (String) var4.next();
                if (!sql.toString().endsWith("SELECT")) {
                    sql.append(",");
                }
            }

            sql.append(" FROM " + this.DBTable.getName());
        }

        sql.append(" WHERE ");
        List<Object> paramList = new ArrayList();
        Iterator var8 = param.entrySet().iterator();

        while (var8.hasNext()) {
            Map.Entry<String, Object> entry = (Map.Entry) var8.next();
            if (sql.toString().endsWith("?")) {
                sql.append(" and ");
            }

            sql.append((String) entry.getKey() + " = ?");
            paramList.add(entry.getValue());
        }

        return this.jdbcTemplate.queryForList(sql.toString(), paramList.toArray());
    }

    public void syncColumn() {
        if (this.isTableCreated()) {
            Set<String> dbColumnNames = new HashSet();
            Iterator var2 = this.getDbTable().getColumns().iterator();

            DBColumn DBColumn;
            while (var2.hasNext()) {
                DBColumn = (DBColumn) var2.next();
                dbColumnNames.add(DBColumn.getName());
            }

            var2 = dbColumnNames.iterator();

            while (var2.hasNext()) {
                String columnName = (String) var2.next();
                if (this.DBTable.getColumn(columnName) == null) {
                    this.dropColumn(columnName);
                }
            }

            var2 = this.DBTable.getColumns().iterator();

            while (var2.hasNext()) {
                DBColumn = (DBColumn) var2.next();
                if (!dbColumnNames.contains(DBColumn.getName())) {
                    this.addColumn(DBColumn);
                }
            }

        }
    }

    public DBTable<DBColumn> getDbTable() {

        return null;
    }


}
